package com.hp.bon.sgw.wh.channel.handler;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.start.SpringContext;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.service.UserResourceConfigService;
import com.hp.bon.sgw.wh.utils.LogUtil;
import com.hp.bon.sgw.wh.utils.ResultCodeUtil;
import com.hp.ocs.diameter.message.*;
import org.simpleframework.http.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class QryInstantFeeListHandle implements IAsynCallHandler {
	private static final Logger _log = LoggerFactory.getLogger(QryInstantFeeListHandle.class);
	private PrintStream printStream;
    private long startTime;
    private Request request;
    private UserResourceConfigService userResourceConfigService ;
    private JSONObject jsonContent;
    public QryInstantFeeListHandle(PrintStream printStream, Request request, long startTime,JSONObject jsonContent) {
		this.printStream = printStream;
        this.startTime = startTime;
        this.request = request;
        this.jsonContent=jsonContent;
    }

	@Override
	public int getProtocolType() {
		return 0;
	}

	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;
		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}
		if (response == null) {
			int _retcodeTmp = callParam.getRetCode() == 3002 ? 11202 : callParam.getRetCode();
			ack = SoapChannel.createERRAnwser(callParam.getSessionId(), _retcodeTmp, callParam.getResultMsg());
			callParam.setServiceResultCode(_retcodeTmp);
		} else {
			if (response instanceof Message) {
				ack = BuzProcessorManager.getInstance().convertMessageToAck(callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				_log.warn("unknown response type:" + callParam.getResponse().getClass().getName());
			}
		}
		try {
			String respXML = convertResponseString(response, callParam.getServiceResultCode());

			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();
			callParam.setResponse(ack);
//			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库
//				MessageDetail detail = new MessageDetail();
//				detail.setBusinessCallId(callParam.getBussinessCallId());
//				detail.setSessionId(callParam.getSessionId());
//				detail.setServiceContextId(callParam.getServiceContextId());
//				detail.setMessageType(MessageType.WSA);
//				detail.setDetails(ack.getDATA());
//				detail.setMsgTime(new Date(ack.getMsgTime()));
//				detail.setOpType("send");
//				detail.setHostId(callParam.getUserName());
//				MessageDetailCacheManager.getInstance().add(detail);
//			}
            //记录到日志
            LogUtil.saveLogToABM(request,respXML,startTime);
			TaskManager.taskProcess(callParam);
            _log.info("http response(returnBalance) " + respXML);
		} catch (UnsupportedEncodingException e) {
			_log.info("convertResponseString UnsupportedEncodingException error,msg=" + e.getMessage());
		} catch (IOException e) {
			_log.info("convertResponseString IOException,msg=" + e.getMessage());
		}
	}

	
	
	/**
	 * 从Message中解析出需要的数据，并拼接成json字符串
	 * @param answer
	 * @param serviceResultCode
	 * @return
	 */
	private  String convertResponseString(Object answer, int serviceResultCode) {
        userResourceConfigService = SpringContext.getApplicationContext().getBean(UserResourceConfigService.class);
        String response="";
        _log.info("QryInstantFeeListHandle serviceResultCode = {}", serviceResultCode);
        _log.info("===========service_result_code===============" + serviceResultCode);
        Map<String, Object> map = getAvpsFromMessage((Message) answer);
        Map<String, Object> data = new HashMap<String, Object>();
        if(map == null){
            data.put("sumCharge",0);
            data.put("resultCode", "-1");
            data.put("resultMsg", "查询失败");
        }else if (serviceResultCode == 0) {
            data.putAll(map);
        } else {
			data.put("sumCharge",0);
			data.put("resultCode", serviceResultCode+"");
			data.put("resultMsg", "查询失败");
        }
        _log.info("QryInstantFeeListHandle convertResponseString = {}", response);
        String newCode = ResultCodeUtil.updateResultCode(data.get("resultCode"), userResourceConfigService.getValue("api_resultCode"), userResourceConfigService.getValue("api_defaultResult"));
        data.put("resultCode", newCode);
        Gson gson = new Gson();
		response = gson.toJson(data);
		return response;
	}

    /**
     * 处理CCA结果
     * @param answer
     * @return
     */
    public Map<String, Object> getAvpsFromMessage(Message answer) {
        Map<String, Object> map = new HashMap<String, Object>();
        List<Map<String,Object>> itemInformationList=new ArrayList<Map<String, Object>>();
        try {
            AVP avp = answer.find(Constants.DIAMETER_AVP_SERVICE_INFOMATION, Constants.DIAMETER_VENDOR_3GPP);
            AVP_Grouped avpServiceInfomation = new AVP_Grouped(avp);
            AVP[] avps = avpServiceInfomation.queryAVPs();
            for (AVP avpData : avps) {
                //Result
                if (avpData.code() == 20631 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                    map.put("resultCode", String.valueOf(new AVP_Unsigned32(avpData).queryValue()));
                }
                //Para_Field_Result
                if (avpData.code() == 80407 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                    map.put("resultMsg", String.valueOf(new AVP_UTF8String(avpData).queryValue()));
                }
                //Total_Charge
                if (avpData.code() == 80141 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                    map.put("sumCharge", new AVP_Integer64(avpData).queryValue());
                }
                //item_Information
                if (avpData.code() == 81170 && avpData.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                    Map<String,Object> itemInformationMap=new HashMap<String, Object>();
                    //Acct_Name
                   String acctName= new AVP_UTF8String(avpServiceInfomation.find(80108, 81000)).queryValue();
                    itemInformationMap.put("acctName",acctName);
                    for (AVP avpTemp : new AVP_Grouped(avpData).queryAVPs()) {
                        //Parent_Class_Id
                        if (avpTemp.code() == 80443 && avpTemp.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            itemInformationMap.put("parentClassId", new AVP_Unsigned32(avpTemp).queryValue());
                        }
                        //Charge
                        if (avpTemp.code() == 81171 && avpTemp.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            itemInformationMap.put("charge", new AVP_Integer64(avpTemp).queryValue());
                        }
                        //Class_Id
                        if (avpTemp.code() == 80441 && avpTemp.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            itemInformationMap.put("classId", new AVP_Unsigned32(avpTemp).queryValue());
                        }
                        //Charge_type_Name
                        if (avpTemp.code() == 80322 && avpTemp.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            itemInformationMap.put("chargeTypeName", new AVP_UTF8String(avpTemp).queryValue());
                        }
                        //Show_level
                        if (avpTemp.code() == 80328 && avpTemp.vendorID() == Constants.DIAMETER_VENDOR_CT) {
                            itemInformationMap.put("showLevel", new AVP_Unsigned32(avpTemp).queryValue()+"");
                        }
                    }
                    itemInformationList.add(itemInformationMap);
                }
            }
            map.put("itemInformationList",itemInformationList);
        } catch (Exception e) {
            map = null;
            _log.error("getAvpsFromMessage Exception error,msg=" ,e);
        }
        return map;
    }
	
}
